#pragma once
#ifndef _BOARD_H_
#define _BOARD_H_

#include "..\Engine\Base\Base.h"
#include "..\Engine\Base\Types.h"
#include "..\Engine\Logic\Level.h"
#include <string>
#include <vector>

#define VEL_ANIMATION_MOVE 200
#define VEL_EXPLOSION 50
#define ADDED_SIZE 5
#define TIME_EXPLOSION 0.1f
#define VEL_ANIMATION_DOWNGEMS 400
#define VEL_ANIMATION_NEWGEMS 200
#define VEL_POINTS -50
#define TIME_POINTS 1.f
#define MIN_LINE_GEMS 3
#define MIN_SCORE 5

//****** Forward declarations ****
class CGem;
//*******************************

class CBoard : public CLevel
{
private:	
	typedef enum EBoardState{ BS_PAUSED=0,
							  BS_WAIT_SEL1,
							  BS_WAIT_SEL2,
							  BS_PLAY_ANIMATION_MOVE,
							  BS_ANIMATION_MOVE,							  
							  BS_EVALUATE_MOVE,
							  BS_PLAY_ANIMATION_ROLLBACK_MOVE,							  
							  BS_ANIMATION_ROLLBACK_MOVE,							  
							  BS_PLAY_ANIMATION_EXPLOSION,
							  BS_ANIMATION_EXPLOSION,
							  BS_PLAY_ANIMATION_DOWNGEMS,
							  BS_ANIMATION_DOWNGEMS,
							  BS_PLAY_ANIMATION_NEWGEMS,							  							 							  
							  BS_ANIMATION_NEWGEMS,
							  BS_EVALUATE_BOARD,
							  BS_RESET_BOARD };

	typedef struct ContainerData
	{
		float	x,y;
		float	w,h;
		CGem*	Gem;		
		bool	MarkedUp;
		bool	MarkedDown;
		bool	MarkedLeft;
		bool	MarkedRight;
	};
	typedef std::vector<ContainerData> TRow;

	std::vector<TRow>	m_BoardData;
	int32				m_Rows;
	int32				m_Columns;
	int32				m_ContainersWidth;
	int32				m_ContainersHeight;
	EBoardState			m_eBoardState;
	int32				m_SelectedRow1, m_SelectedCol1;	
	int32				m_SelectedRow2, m_SelectedCol2;	
	std::vector<CGem*>  m_FreeGems;	
	float				m_TimeCounter;
	int32				m_Score;
	int32				m_ScoreMultiplier;

	EBoardState GetState() const {return m_eBoardState;}
	void		SetState(const EBoardState State) {m_eBoardState = State;}
	void SwitchGems(int32 row1, int32 col1, int32 row2, int32 col2);
	void SetGem(int32 row, int32 col, CGem* Gem);
	void EvaluateGem(int32 row, int32 col);
	bool GemMarked(int32 row, int32 col);
	void ClearMarked();	
	void ClearSelected();
	bool ExistMarked();
	bool ExistHoles(int32 col);
	bool ColumnIsFull(int32 col); 
	void Reset();	
	void AnimationMove(float dt);
	void AnimationRollback(float dt);	
	void AnimationExplosion(float dt);
	void AnimationDownGems(float dt);
	void AnimationDownColumn(int32 col, float dt);
	void AnimationNewGems(float dt);
	void EvaluateBoard();
	void ResetFreeGems(); 
	void AddScore();
	void ShowScore(float x, float y, int32 Score);

public:
	CBoard(int32 rows, int32 columns);
	~CBoard();	

	void Init(int32 x, int32 y, int32 Width, int32 Height);	
	void SelectGem(const int32 x,const int32 y);	
	void Stop();
	void Start();
	int32 GetScore() const {return m_Score;}
	
	void Update(float dt);
};


#endif